package com.wm.machine.baselibrary.utils.zxing.utils;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import java.util.Hashtable;

/**
 * Author： chengxp
 * CreatTime： 2018/1/29
 * Description: 二维码生成工具类
 */

public final class EncodeUtils {
  private EncodeUtils() {

  }

  private static final String TAG = EncodeUtils.class.getSimpleName();

  private static final int WHITE = 0xFFFFFFFF;
  private static final int BLACK = 0xFF000000;
  private static final int TWO = 2;

  private static final String CHARSET = "utf-8";
  /**
   * 二维码尺寸
   */
  private static final int QRCODE_SIZE = 300;
  /**
   * logo 占整个二维码的大小
   */
  private static final int LOGO_PERCENT = 5;


  /**
   * 生成二维码
   *
   * @param content 二维码的内容
   * @return 返回二维码的bitmap
   */
  public static Bitmap createQRCodeBitmap(String content) {
    return createCodeBitmap(content, BarcodeFormat.QR_CODE);
  }

  /**
   * 生成带有logo的二维码
   *
   * @param content 二维码的显示的内容
   * @param logo 要添加的logo的bitmap
   * @return 生成的bitmap
   */
  public static Bitmap createQRWithLogoBitmap(String content, Bitmap logo) {
    Bitmap qrCode = createCodeBitmap(content, BarcodeFormat.QR_CODE);
    return addLogo(qrCode, logo);
  }

  /**
   * 创建带有logo的二维码图片
   *
   * @param content 二维码的具体内容
   * @param resources 资源类
   * @param rid 资源ID
   * @return 二维码的bitmap
   */
  public static Bitmap createQRWithLogoBitmap(String content, Resources resources, int rid) {
    Bitmap logo = BitmapFactory.decodeResource(resources, rid);
    Bitmap qrCode = createCodeBitmap(content, BarcodeFormat.QR_CODE);
    return addLogo(qrCode, logo);
  }

  /**
   * 生成对应编码的bitmap
   *
   * @param content 二维码内容
   * @param format 格式：QR ，code_128 等
   * @return 对应码的bitmap
   */
  public static Bitmap createCodeBitmap(String content, BarcodeFormat format) {
    Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    hints.put(EncodeHintType.MARGIN, 1);
    MultiFormatWriter mFormatWriter = new MultiFormatWriter();
    BitMatrix mBitMatrix = null;
    try {
      mBitMatrix = mFormatWriter.encode(content, format, QRCODE_SIZE, QRCODE_SIZE, hints);
    } catch (WriterException e) {
      e.printStackTrace();
    }
    int width = mBitMatrix.getWidth();
    int height = mBitMatrix.getHeight();
    int[] pixels = new int[width * height];
    for (int y = 0; y < height; y++) {
      int offset = y * width;
      for (int x = 0; x < width; x++) {
        pixels[offset + x] = mBitMatrix.get(x, y) ? BLACK : WHITE;
      }
    }
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return bitmap;
  }

  /**
   * 图形中间插入logo
   *
   * @param original 原始二维码
   * @param logo 插入的logo
   * @return 添加logo后的bitmap
   */
  private static Bitmap addLogo(Bitmap original, Bitmap logo) {
    Bitmap mBitmap = null;
    if (null == original || original.getWidth() == 0 || original.getHeight() == 0) {
      return null;
    }

    if (logo == null || logo.getWidth() == 0 || logo.getHeight() == 0) {
      mBitmap = original;
    }

    // 获取图片的宽高
    int srcWidth = original.getWidth();
    int srcHeight = original.getHeight();
    int logoWidth = logo.getWidth();
    int logoHeight = logo.getHeight();
    // logo大小为二维码整体大小的1/5
    float scaleFactor = srcWidth * 1.0f / LOGO_PERCENT / logoWidth;
    mBitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
    try {
      Canvas canvas = new Canvas(mBitmap);
      canvas.drawBitmap(original, 0, 0, null);
      canvas.scale(scaleFactor, scaleFactor, srcWidth / TWO, srcHeight / TWO);
      canvas.drawBitmap(logo, (srcWidth - logoWidth) / TWO, (srcHeight - logoHeight) / TWO, null);
      canvas.save(Canvas.ALL_SAVE_FLAG);
      canvas.restore();
    } catch (Exception e) {
      mBitmap = null;
      e.getStackTrace();
    }
    return mBitmap;
  }


}
